﻿using NHibernate;
using NHibernate.Cfg;
using NHibernate.Driver;
using NHibernate.Dialect;
using System.ComponentModel.DataAnnotations;
using System.Reflection;
using DoNet.Entitys;

namespace DoNet.ORM.Repository.NHiberbate
{
    /// <summary>
    /// 
    /// </summary>
    public class SessionFactoryHelper
    {
        /// <summary>
        /// 
        /// </summary>
        [Required]
        public ISessionFactory _sessionFactory;
        /// <summary>
        /// 
        /// </summary>
        /// <param name="dataBaseType"></param>
        /// <param name="connectionString"></param>
        public SessionFactoryHelper(DataBaseType dataBaseType, string connectionString)
        {
            var configuration = new Configuration();
            // 使用配置文件初始化配置 加载 hibernate.cfg.xml 基础配置
            //configuration.Configure(); 
            /*
            ‌NHibernate.Dialect.HSQLDialect‌：适用于HSQLDB数据库。 
            */
            configuration.DataBaseIntegration(db =>
            {
                db.ConnectionString = connectionString;
                switch (dataBaseType)
                {
                    case DataBaseType.SqlServer:
                        db.Driver<MicrosoftDataSqlClientDriver>();
                        db.Dialect<MsSql2012Dialect>(); //MsSql2000Dialect, MsSql2005Dialect, MsSql2008Dialect, MsSql2012Dialect, MsSql7Dialect, MsSqlAzure2008Dialect, MsSqlCe40Dialect, MsSqlCeDialect。
                        break;
                    case DataBaseType.MySql:
                        db.Driver<MySqlDataDriver>();
                        db.Dialect<MySQLDialect>(); //MySQL55Dialect, MySQL55InnoDBDialect, MySQL57Dialect, MySQL5Dialect, MySQL5InnoDBDialect, MySQL8Dialect, MySQL8InnoDBDialect, MySqlDialect, SqlServerDialect。
                        break;
                    case DataBaseType.Oracle:
                        db.Driver<OracleDataClientDriver>();
                        db.Dialect<Oracle12cDialect>(); //OracleLiteDialect, Oracle8iDialect, Oracle9iDialect, Oracle10gDialect, Oracle12cDialect。
                        break;
                    case DataBaseType.PostgreSQL:
                        db.Driver<NpgsqlDriver>(); //NpgsqlDriver
                        db.Dialect<PostgreSQLDialect>(); //PostgreSQL81Dialect, PostgreSQL82Dialect, PostgreSQL83Dialect, PostgreSQLDialect。
                        break;
                    case DataBaseType.Sqlite:
                        db.Driver<SQLite20Driver>();  //SQLite20Driver
                        db.Dialect<SQLiteDialect>();
                        break;
                    //case DataBaseType.DB2:
                    //    db.Driver<DB2Driver>();  //DB2400Driver, DB2CoreDriver, DB2Driver
                    //    db.Dialect<DB2Dialect>(); //DB2400Dialect, DB2Dialect
                    //    break;
                    case DataBaseType.Dm:
                        db.Driver<OdbcDriver>();  //
                        db.Dialect<DmDialect>(); //自定义
                        break;
                    case DataBaseType.Kdbndp:
                        db.Driver<OdbcDriver>();  //
                        db.Dialect<KdbndpDialect>(); //自定义
                        break;
                }
                db.Timeout = 30;
                db.LogSqlInConsole = true; // 启用 SQL 日志
            });

            configuration.SetProperty("show_sql", "true"); // 显示SQL语句
            configuration.SetProperty("cache.use_second_level_cache", "true"); // 启用二级缓存
            //configuration.SetProperty("cache.provider_class", "NHibernate.Caches.SysCache2.SysCacheProvider, NHibernate.Caches.SysCache2"); // 设置缓存提供者
            //var sessionFactory = configuration.BuildSessionFactory();

            //configuration.AddAssembly(typeof(Sys_Area).Assembly); // 自动扫描程序集以查找映射
            var assembly = Assembly.Load("DoNet.Entitys");
            configuration.AddAssembly(assembly); // 添加实体类所在的程序集
            _sessionFactory = configuration.BuildSessionFactory();
        }
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public ISession OpenSession()
        {
            return _sessionFactory.OpenSession();
        }
    }
}
